home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
- York. Permission is granted to any individual or institution to use this
- software as long as it is not sold for profit. This copyright notice must be
- retained. This software may not be included in commercial products without
- written permission of Columbia University.
- */
- /*
- Many changes since those below by many people, 1988-1992:
- Matthias Aebi, Paul Placeway, Rick Watson, Frank da Cruz, ...
- */
- /* Version 0.9(37) - Paul Placeway at Ohio State, Jan 1988 */
- /* reformatted all of the code so that it would be 79 or fewer colums */
- /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */
- /* Ported to Megamax native Macintosh C compiler. */
- /* Original work done by Bill Catchings and Bill Schilit at Columbia Univ */
- /* using the SUMACC cross compiler, 1984, adapted from UNIX ckufio.c... */
- /* Edit by Bill on Thu May 30, 00:18 */
- /* Do error handling, neaten up comments, and some code. */
- /* Edit by Bill on Wed May 15, 16:09 */
- /* Make zrtol call common sfprtol, .RSRC overrides default settings */
- /* ckmfio.c, Mon Apr 29 17:48, Edit by Bill*2 */
- /* Put null in translated name to tie it off. */
- /* Make author text of new file to ???? instead of random string */
- /* Do flushvol after closing a file */
- /* Bill C., Apr 24 */
- /* Change zchin to allow sending of files with high order bits on */
- /* Bill C., Apr 22 */
- /* Add error handling (informing) for more cases, e.g. can't delete */
- /* Bill C., Apr 22 */
- /* Fix Resource/Data fork stuff. Uppercase things where needed */
- /* ckzmac.c, Thu Apr 21 17:19, Edit by Bill */
- /* Ignore trying to close an not-openend file, driver does it alot */
- /* ckzmac.c, Thu Apr 11 21:18, Edit by Bill */
- /* Catch error in ZOPENO when trying to open an existing file */
- /* ckzmac.c, Thu Apr 14 20:07, Edit by Bill */
- /* Translate calls with ZCTERM to go to the console routines */
-
- /*
- File ckmfio -- Kermit file system support for the Macintosh
- */
-
- /*
- Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
- York. Permission is granted to any individual or institution to use, copy, or
- redistribute this software so long as it is not sold for profit, provided this
- copyright notice is retained.
- */
-
- /* Definitions of some Unix system commands */
-
- char *ckzv = "File support, 5A(081), 24 Jan 92";
-
- #include "ckuver.h" /* Version herald */
- char *ckzsys = HERALD;
-
- #define DIRCMDSTR "ls"
- #define DELCMDSTR "rm"
- #define SPCCMDSTR "sp"
-
- char *DIRCMD = DIRCMDSTR; /* For directory listing */
- char *DIRCM2 = DIRCMDSTR; /* For long directory listing */
- char *DELCMD = DELCMDSTR; /* For file deletion */
- char *SPACMD = SPCCMDSTR; /* Space for all available volumes */
- char *TYPCMD = ""; /* For typing a file */
- char *SPACM2 = ""; /* For space in specified directory */
- char *WHOCMD = ""; /* For seeing who's logged in */
-
- /*
- Functions (n is one of the predefined file numbers from ckermi.h):
-
- zopeni(n,name) -- Opens an existing file for input.
- zopeno(n,name) -- Opens a new file for output.
- zclose(n) -- Closes a file.
- zchin(n) -- Gets the next character from an input file.
- zinfill() -- (re) fill file input buffer, return the first character
- zsout(n,s) -- Write a null-terminated string to output file, buffered.
- zsoutl(n,s) -- Like zsout, but appends a line terminator.
- zsoutx(n,s,x) -- Write x characters to output file, unbuffered.
- zchout(n,c) -- Add a character to an output file, unbuffered.
- zchki(name) -- Check if named file exists and is readable, return size.
- zchko(name) -- Check if named file can be created.
- znewn(name,s) -- Make a new unique file name based on the given name.
- zdelet(name) -- Delete the named file.
- zxpand(string) -- Expands the given wildcard string into a list of files.
- znext(string) -- Returns the next file from the list in "string".
- zxcmd(cmd) -- Execute the command in a lower fork.
- zclosf() -- Close input file associated with zxcmd()'s lower fork.
- zrtol(n1,n2) -- Convert remote filename into local form.
- zltor(n1,n2) -- Convert local filename into remote form.
- zchdir(dirnam) -- Change working directory.
- zhome() -- Return pointer to home directory name string.
- zkself() -- Kill self, log out own job.
- */
-
- #include "ckcdeb.h" /* Debug() and tlog() defs */
- #include "ckcasc.h" /* ASCII character symbols */
- #include "ckcker.h" /* Kermit definitions */
-
- #include "ckmdef.h" /* Common Mac module definitions */
- #include "ckmres.h" /* Resource defs */
- #include "ckmasm.h" /* Assembler code */
- #include "ckmptp.h" /* ckm* Prototypes */
- #include "ckmwin.h"
-
- #ifdef MPW32
- #define hfileInfo hFileInfo /* for compat with newer .h files */
- #endif /* MPW32 */
-
- /* (PWP) external def. of things used in buffered file input and output */
- extern char *zinbuffer, *zoutbuffer;
- extern char *zinptr, *zoutptr;
- extern int zincnt, zoutcnt;
- static long zcnt_written;
-
- /* These should all be settable by the File Settings Menu */
-
- #define FS_WIND 1 /* file is a text edit buffer */
- #define FS_OPEN 2 /* file has been opened */
- #define FS_RSRC 4 /* opened in resource fork */
- #define FS_DATA 8
- #define FS_PIPE 16 /* file is a memory buffer */
- #define FS_MACB 32 /* we are sending a file in MacBinary format */
-
- MACFILE fp[ZNFILS] = { /* File information */
- {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL},
- {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL},
- {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL}
- };
-
- static long iflen = -1; /* Input file length */
- static long oflen = -1; /* Output file length */
-
- char printfbuf[256];
-
- /****************************************************************************/
- /* Z O P E N I -- Open an existing file for input.
- *
- * The file name has been returned from and the volume reference
- * number set by SFGetFile.
- *
- * Returns:
- * TRUE: file opened ok
- * FALSE: some error.
- */
- /****************************************************************************/
- zopeni (n, name)
- int n;
- char *name;
- {
- int err;
- register MACFILE *fpp;
-
- if (chkfn (n)) {
- printerr ("At zopeni file is already open ", n);
- return (FALSE);
- }
- zincnt = 0; /* (PWP) clear buffer input count */
- fpp = &fp[n];
-
- if (n == ZCTERM) { /* Terminal open? */
- if (chkfn (ZIFILE)) /* Check current ZOFILE */
- printerr ("ZIFILE already open...: ", n);
- fp[ZIFILE].fstatus = FS_WIND; /* redirect... here it is */
- fpp->fstatus = FS_WIND; /* Indicate this is open too */
- return (conopen ()); /* Return from low level open */
- }
- if (n == ZSYSFN) /* trying to open a pipe? */
- return (zmxcmd (name)); /* yes... */
-
- if (n == ZIFILE) { /* opening input file? */
- /* if we are doing MacBinary format */
- if ((filargs.filflg & (FIL_RSRC|FIL_DATA)) == (FIL_RSRC|FIL_DATA)) {
- err = macbinopen(name, fpp);
- if (err == noErr)
- return (TRUE);
- else
- return (ioutil (err));
- } else {
- if (filargs.filflg & FIL_RSRC) /* and they said resource? */
- err = OpenRF_rdonly (c2p_tmp(name), filargs.filvol,
- &fpp->frefnum);
- else /* else some other channel or data */
- err = FSOpen_rdonly (c2p_tmp(name), filargs.filvol,
- &fpp->frefnum);
- if (err != noErr) /* check for open error */
- return (ioutil (err)); /* failed... */
- }
- }
-
- fpp->fstatus = FS_OPEN | ( /* set flags */
- (filargs.filflg & FIL_RSRC) ? FS_RSRC : FS_DATA);
-
- GetEOF (fpp->frefnum, &filargs.filsiz); /* set size for screen */
-
- #ifdef COMMENT
- fsize = filargs.filsiz; /* PWP: set size for screen */
- #endif
-
- return (TRUE); /* Return success */
- } /* zopeni */
-
- MBHead filHead;
- static char MBname[64];
-
- void
- bzero (b, n)
- register char *b;
- register int n;
- {
- while (n-- > 0)
- *b++ = 0;
- }
-
- void
- bcopy (a, b, n)
- register char *a, *b;
- register int n;
- {
- while (n-- > 0)
- *b++ = *a++;
- }
-
- /* these next three taken from NCSA Telnet 2.2 */
- int
- GetFileInfo(vol,name,iop)
- short vol;
- char *name;
- ParamBlockRec *iop;
- {
- char thename[64];
-
- strncpy (thename, name, 64); /* make my own copy of this */
- thename[63] = '\0';
- c2pstr(thename);
-
- iop->fileParam.ioNamePtr = thename;
- iop->fileParam.ioVRefNum=vol;
- iop->fileParam.ioFVersNum=iop->fileParam.ioFDirIndex=0;
- PBGetFInfo(iop, FALSE);
- return (iop->fileParam.ioResult);
- }
-
- int
- SetFileInfo(vol,name,iop)
- short vol;
- char *name;
- ParamBlockRec *iop;
- {
- char thename[64];
-
- strncpy (thename, name, 64); /* make my own copy of this */
- thename[63] = '\0';
- c2pstr(thename);
-
- iop->fileParam.ioNamePtr = thename;
- iop->fileParam.ioVRefNum=vol;
- iop->fileParam.ioFVersNum=iop->fileParam.ioFDirIndex=0;
- PBSetFInfo(iop, FALSE);
- return (iop->fileParam.ioResult);
- }
-
- int
- MakeTextFile(vol,name,iop)
- short vol;
- char *name;
- ParamBlockRec *iop;
- {
- GetFileInfo(vol,name,iop);
- iop->fileParam.ioFlFndrInfo.fdType='TEXT';
- iop->fileParam.ioFlFndrInfo.fdCreator='EDIT';
- SetFileInfo(vol,name,iop);
- return (iop->fileParam.ioResult);
- }
-
- int
- macbinopen(name, fpp)
- char *name;
- MACFILE *fpp;
- {
- ParamBlockRec finfo;
- int err;
-
- /* open first fork of name for reading and fill input buffer
- with MacBinary header */
- /* save file name for later */
- strncpy (MBname, name, 64);
- MBname[64] = 0;
-
- /* clear out the header */
- bzero (&filHead, sizeof(MBHead));
-
- /* put the name into place */
- strncpy (&filHead.name[0], name, 64);
- filHead.name[63] = '\0';
- c2pstr(filHead.name);
-
- /* get the file info */
- if ((err = GetFileInfo( filargs.filvol, name, &finfo)) != noErr) {
- printerr("macbinopen: problem with GetFileInfo", err);
- return (err);
- }
-
- bcopy( &finfo.fileParam.ioFlFndrInfo, &filHead.type[0], sizeof(FInfo) );
- filHead.protected = (filHead.zero2 & 0x40)?1:0;
- filHead.zero2 = 0;
- bcopy(&finfo.fileParam.ioFlLgLen, &filHead.dflen[0], 4);
- bcopy(&finfo.fileParam.ioFlRLgLen, &filHead.rflen[0], 4);
- bcopy(&finfo.fileParam.ioFlCrDat, &filHead.cdate[0], 4);
- bcopy(&finfo.fileParam.ioFlMdDat, &filHead.mdate[0], 4);
-
- filargs.filsiz=finfo.fileParam.ioFlLgLen;
- filargs.rsrcsiz=finfo.fileParam.ioFlRLgLen;
-
- #ifdef COMMENT
- fsize = ((filargs.filsiz + 127) & ~127)
- + ((filargs.rsrcsiz + 127) & ~127)
- + 128;
- #endif
-
- bcopy (&filHead, zinbuffer, 128); /* put header in xfer buffer */
- zincnt = 128; /* init buffer to 128 to send */
- zinptr = zinbuffer; /* set pointer to beginning, (== &zinbuffer[0]) */
-
- if (filargs.filsiz <= 0) {
- /* no data fork, open the resource fork */
- if ((err = OpenRF_rdonly(c2p_tmp(name),
- filargs.filvol, &fpp->frefnum)) != noErr) {
- printerr("macbinopen: problem with OpenRF", err);
- return (err);
- }
- fpp->fstatus = FS_OPEN | FS_RSRC | FS_MACB;
- } else {
- /* we do the data fork first, then the resource fork */
- if ((err = FSOpen_rdonly (c2p_tmp(name),
- filargs.filvol, &fpp->frefnum)) != noErr) {
- printerr("macbinopen: problem with FSOpen", err);
- return (err);
- }
- fpp->fstatus = FS_OPEN | FS_DATA | FS_MACB;
- }
- return (noErr);
- }
-
- /* is this a MacBinary I header -- see standard-macbinary-ii.txt (on Sumex) */
- is_macbinary(h)
- MBHead h;
- {
- long l;
-
- if ((h.zero1 != 0) || (h.zero2 != 0) || (h.zero3 != 0)) {
- printerr("zeros", 0);
- return (0);
- }
- if ((h.name[0] == 0) || (h.name[0] & 0xc0)) {
- printerr("name length", h.name[0]);
- return (0);
- }
- bcopy (&h.dflen[0], &l, 4);
- if ((l < 0) || (l > 0x7fffff)) {
- printerr("data length", l);
- return (0);
- }
- bcopy (&h.rflen[0], &l, 4);
- if ((l < 0) || (l > 0x7fffff)) {
- printerr("rsrc length", l);
- return (0);
- }
- #ifdef COMMENT
- /* MacBinary II uses this area for more stuff, so don't check it */
- for (i = 2; i < 27; i++) {
- if (h.filler[i] != 0) {
- printerr("filler index:", i);
- return (0);
- }
- }
- #endif /* COMMENT */
- return (1);
- }
-
-
- /****************************************************************************/
- /* Z O P E N O -- Open a new file for output.
- *
- * Returns:
- * TRUE: File opened ok
- * FALSE: some error has occured or channel occupied.
- *
- */
- /****************************************************************************/
-
- short zopo_vrefnum = 0; /* a hack for where to put the file */
-
- zopeno (n, name, zz, fcb)
- int n;
- char *name;
- struct zattr *zz;
- struct filinfo *fcb;
- {
- OSType forktext, authortext;
- int err;
- FInfo finfo;
- register MACFILE *fpp;
- short the_vrefnum;
-
- #ifdef notdef
- if ((zz != NULL) || (fcb != NULL)) {
- printerr ("zopeno: zz or fcb not NULL", 0);
- return(FALSE);
- }
- #endif
-
- if (chkfn (n)) {
- printerr ("zopeno - file is already open: ", n);
- return (FALSE);
- }
- fpp = &fp[n];
-
- if (n == ZDFILE) { /* debugging open? */
- if (chkfn (n)) /* Check current ZOFILE */
- printerr ("Console already open...: ", n);
- fp[n].fstatus = FS_WIND; /* yes, redirect... here it is */
- return (conopen ()); /* Return from low level open */
- }
- if (n == ZCTERM || n == ZSTDIO) { /* Terminal open? */
- if (chkfn (ZOFILE)) /* Check current ZOFILE */
- printerr ("ZOFILE already open...: ", n);
- fp[ZOFILE].fstatus = FS_WIND; /* yes, redirect... here it is */
- fpp->fstatus = FS_WIND; /* Indicate this is open too */
- zoutcnt = 0; /* (PWP) reset output buffer */
- zoutptr = zoutbuffer;
- return (conopen ()); /* Return from low level open */
- }
- if (n == ZOFILE) {
- zoutcnt = 0; /* (PWP) reset output buffer */
- zoutptr = zoutbuffer;
- if ((filargs.filflg & (FIL_RSRC|FIL_DATA)) == (FIL_RSRC|FIL_DATA)) {
- /* if MacBinary */
- forktext = 'TEXT'; /* a text file, because we don't */
- authortext = '????'; /* know what else to do with it. */
- } else if (filargs.filflg & FIL_RSRC) {
- forktext = 'APPL';
- authortext = '????';
- } else {
- forktext = 'TEXT'; /* Make fork reflect fork choice */
- authortext = 'MACA'; /* set creator to "MacWrite" */
- }
- the_vrefnum = filargs.filvol;
- }
- else
- { /* a file, but not the transfer output file */
- if (zopo_vrefnum)
- the_vrefnum = zopo_vrefnum;
- else
- the_vrefnum = filargs.filvol; /* same as for transfers */
- zopo_vrefnum = 0; /* we've now used this */
- }
-
- err = Create (c2p_tmp(name), the_vrefnum, authortext, forktext);
- if (err == dupFNErr) { /* duplicate file? */
- if (!ioutil (FSDelete (c2p_tmp(name), /* Try to delete it */
- the_vrefnum))) /* checking for failure */
- return (FALSE); /* failed... */
- err = Create (c2p_tmp(name), the_vrefnum, /* recreate */
- authortext, forktext);
- }
- if (err != noErr) /* some error? */
- return (ioutil (err)); /* yes, do message and return */
-
- if (n == ZOFILE) { /* is it our transferred file? */
- /* set file's folder from filargs.filfldr which is either the */
- /* applications folder or the settings file folder */
-
- /* read current finder info */
- GetFInfo (c2p_tmp(name), the_vrefnum, &finfo);
- finfo.fdFldr = filargs.filfldr; /* set new folder */
- /* and tell system about it */
- SetFInfo (c2p_tmp(name), the_vrefnum, &finfo);
-
- zcnt_written = 0;
- /* if we are doing MacBinary format */
- if ((filargs.filflg & (FIL_RSRC|FIL_DATA)) == (FIL_RSRC|FIL_DATA)) {
- /* save file name for later */
- bzero (MBname, 64); /* clear name buffer */
- strncpy (MBname, name, 64);
- MBname[64] = 0;
- /* we delay opening any forks until we have the MacBin header */
- fp[n].fstatus = FS_OPEN | FS_MACB; /* neither DATA nor RSRC yet */
- return (TRUE); /* done ok */
- } else { /* not MacBinary */
- if (filargs.filflg & FIL_RSRC) /* want to use resource fork? */
- err = OpenRF (c2p_tmp(name), the_vrefnum, /* yes... */
- &fpp->frefnum);
- else /* else data, or some other file */
- err = FSOpen (c2p_tmp(name), the_vrefnum, &fpp->frefnum);
- }
- } else {
- err = FSOpen (c2p_tmp(name), the_vrefnum, &fpp->frefnum);
- }
-
- if (err != noErr) /* able to open? */
- return (ioutil (err)); /* no. fail return now */
-
- if (n == ZOFILE) { /* is it our transferred file? */
- fp[n].fstatus = FS_OPEN |
- ((filargs.filflg & FIL_RSRC) ? FS_RSRC : FS_DATA);
- } else {
- fp[n].fstatus = FS_OPEN | FS_DATA;
- }
-
- return (TRUE); /* done ok */
- } /* zopeno */
-
- /***********************************************************************
- * mbcl_cleanup -- do stuff after closeing an open (for recipt) macbinary file.
- */
- mbcl_cleanup()
- {
- int err = noErr, e2 = 0;
- ParamBlockRec finfo;
- Point old_location;
-
- if (!cxseen && !czseen &&
- (zcnt_written > ((filargs.rsrcsiz + 127) & ~127)) ||
- (zcnt_written < filargs.rsrcsiz)) {
- sprintf(printfbuf, "Resource fork size mismatch: should be %d is %d",
- filargs.rsrcsiz, zcnt_written);
- printerr(printfbuf, 0);
- }
-
- if ((err = GetFileInfo(filargs.filvol, MBname, &finfo)) != noErr) {
- sprintf(printfbuf, "Could not GetFileInfo on \"%s\": error %d",
- MBname, err);
- printerr(printfbuf,0);
- } else {
- old_location = finfo.fileParam.ioFlFndrInfo.fdLocation;
-
- filHead.protected &= 01; /* nuke all but low order bit */
-
- bcopy(&filHead.type[0], &finfo.fileParam.ioFlFndrInfo, sizeof(FInfo));
- bcopy(&filHead.cdate[0], &finfo.fileParam.ioFlCrDat, 4);
- bcopy(&filHead.mdate[0], &finfo.fileParam.ioFlMdDat, 4);
-
- /* As per the MacBinary II doc, I clear the following flags:
- *
- * 0 - Set if file/folder is on the desktop (Finder 5.0 and later)
- * 1 - bFOwnAppl (used internally)
- * 8 - Inited (seen by Finder)
- * 9 - Changed (used internally by Finder)
- * 10 - Busy (copied from File System busy bit)
- */
- finfo.fileParam.ioFlFndrInfo.fdFlags &= 0xf8fc;
-
- /* set new folder */
- /* finfo.fileParam.ioFlFndrInfo.fdFldr = filargs.filfldr; */
- finfo.fileParam.ioFlFndrInfo.fdFldr = 0; /* set new folder */
- /* old_location */
- finfo.fileParam.ioFlFndrInfo.fdLocation = old_location;
-
- if (finfo.fileParam.ioFlLgLen != filargs.filsiz) {
- sprintf(printfbuf,
- "%s: Data fork size mismatch: should be %d is %d",
- MBname, filargs.filsiz, finfo.fileParam.ioFlLgLen);
- printerr(printfbuf, 0);
- }
- if (finfo.fileParam.ioFlRLgLen != filargs.rsrcsiz) {
- sprintf(printfbuf,
- "%s: Resource fork size mismatch: should be %d is %d",
- MBname, filargs.rsrcsiz, finfo.fileParam.ioFlRLgLen);
- printerr(printfbuf, 0);
- }
- /* finfo.fileParam.ioFlRLgLen=out->rlen; */
- /* finfo.fileParam.ioFlLgLen =out->dlen; */
-
- if ((err = SetFileInfo(filargs.filvol, MBname, &finfo)) != noErr)
- printerr("Could not SetFileInfo:", err);
- /* make sure the new data got to disk */
-
- /* try to give it the name encoded in the MacBinary header */
- err = Rename(c2p_tmp(MBname), filargs.filvol, c2p_tmp2(filHead.name));
- if (err != noErr)
- screen(SCR_WM, 0, 0l, "Can't rename file to its MacBinary name.");
-
- err = FlushVol (NILPTR, filargs.filvol);
- }
-
- return (err);
- }
-
-
- /****************************************************************************/
- /* Z C L O S E -- Close the given file.
- *
- * Returns:
- * TRUE: file closed ok.
- * FLASE: some error has occured.
- *
- */
- /****************************************************************************/
- zclose (n)
- int n;
- {
- int err = noErr, e2 = 0;
- register MACFILE *fpp;
-
- if (!chkfn (n)) /* is it opened? */
- return (FALSE); /* no return now */
-
- if ((n == ZOFILE) && (zoutcnt > 0)) /* (PWP) output leftovers */
- e2 = zoutdump();
-
- fpp = &fp[n];
-
- if (fpp->fstatus == FS_WIND) { /* is this a window? */
- fp[ZCTERM].fstatus = 0; /* yes, clear ZCTERM */
-
- } else if (fpp->fstatus == FS_PIPE) { /* is this a pipe? */
- fp[ZSYSFN].fstatus = 0; /* yes, no pipe now, clear ZSYSFN */
-
- } else if (n == ZIFILE) { /* Sending this file? */
- err = FSClose (fpp->frefnum); /* use OS close */
- if (err != noErr)
- printerr("zclose(): problem closing input file:", err);
-
- } else if (n == ZOFILE) { /* recieving this file */
- if (fpp->fstatus & FS_MACB) { /* if MacBinary format */
- if (fpp->fstatus & FS_OPEN) {
- printerr(
- "zclose(): MacBinary botched: this file should NOT still be open", 0);
- err = FSClose (fpp->frefnum); /* close it just to be safe */
-
- if (err == noErr) /* and if that worked */
- /* PWP: the above if should be ==, NOT != !!!!! */
- /* flush buffers in case write worked */
- err = FlushVol (NILPTR, filargs.filvol);
- if (err != noErr)
- printerr("zclose(): problem closing/flushing output file:",
- err);
- }
- } else {
- err = FSClose (fpp->frefnum); /* else use OS close */
-
- if (err != noErr)
- printerr("zclose(): problem closing output file:", err);
-
- /* flush buffers in case write worked */
- err = FlushVol (NILPTR, filargs.filvol);
-
- if (err != noErr)
- printerr("zclose(): problem flushing output disk:", err);
- }
- if (fpp->fstatus & FS_MACB) { /* if MacBinary format */
- err = mbcl_cleanup();
- }
- } else if (n == ZWFILE) { /* if opened by a command */
- err = FSClose (fpp->frefnum); /* else use OS close */
-
- if (err != noErr)
- printerr("zclose(): problem closing output file:", err);
-
- /* flush buffers in case write worked */
- err = FlushVol (NILPTR, filargs.filvol);
-
- if (err != noErr)
- printerr("zclose(): problem flushing output disk:", err);
- } else {
- printerr("zclose(): I don't know what kind of file this is:", n);
- }
-
- fpp->fstatus = 0; /* clear out status word */
- if (n == ZOFILE || n == ZIFILE) /* turn off both flags */
- filargs.filflg &= ~(FIL_RSRC | FIL_DATA);
-
- iflen = -1; /* Invalidate file length */
-
- if (e2 < 0) {
- (void) ioutil (err);
- return (FALSE);
- } else {
- return (ioutil (err)); /* return according to io operations */
- }
- } /* zclose */
-
-
-
- /****************************************************************************/
- /* Z C H I N -- Get a character from the input file.
- *
- * Returns:
- * 0: Ok
- * -1: EOF (or other error).
- *
- */
- /****************************************************************************/
- zchin (n, c)
- int n;
- char *c;
- {
- int err;
- long rdcnt; /* pascal long */
- register MACFILE *fpp;
- register MACPIPE *pipe;
-
- if (n == ZIFILE)
- return (zminchar()); /* (PWP) go through the macro */
-
- if (!chkfn (n))
- return (0);
-
- fpp = &fp[n];
-
- if (fpp->fstatus == FS_WIND) { /* a window? */
- printerr ("zchin called for FS_WIND file: ", n);
- return (0);
- }
- if (fpp->fstatus == FS_PIPE) { /* a pipe? */
- pipe = fpp->fpipe;
-
- if (pipe->charsleft <= 0) { /* test for characters left */
- pipe->currptr = pipe->pipebuf; /* restart at the beginning
- * of the buffer */
-
- if (pipe->refill != NILPROC) { /* refill the pipe if
- * possible */
- saveA0 (); /* push content of A0 to stack */
- /* load the content of refill to A0 */
- loadA0 ((char *) *(pipe->refill));
-
- execute (); /* call the refill procedure */
- restoreA0 (); /* get A0 back from the stack */
- } else
- *(pipe->currptr) = '\0'; /* make it end otherwise */
- }
- if (*(pipe->currptr) == '\0') /* is this eo-pipe? */
- return (-1); /* yes, fail return */
-
- *c = *(pipe->currptr)++;/* read character */
- (pipe->charsleft)--; /* decrement characters left */
-
- return (0); /* success */
- }
- rdcnt = 1;
- err = FSRead (fpp->frefnum, &rdcnt, c);
- if (err == eofErr)
- return (-1); /* Failure return */
- return (ioutil (err) ? 0 : -1); /* success or unknown failure */
- } /* zchin */
-
- /* Z S I N L -- Read a line from a file */
-
- /*
- Writes the line into the address provided by the caller.
- n is the Kermit "channel number".
- Writing terminates when newline is encountered, newline is not copied.
- Writing also terminates upon EOF or if length x is exhausted.
- Returns 0 on success, -1 on EOF or error.
- */
- int
- zsinl(n,s,x) int n, x; char *s; {
- int a, z = 0;
-
- if (chkfn(n) < 1) { /* Make sure file is open */
- return(-1);
- }
- a = -1;
- while (x--) {
- #ifndef NLCHAR
- int old;
- old = a; /* Previous character */
- #endif
- if (zchin(n,&a) < 0) { /* Read a character from the file */
- z = -1;
- break;
- }
- #ifdef NLCHAR
- if (a == (char) NLCHAR) break; /* Single-character line terminator */
- #else
- if (a == '\r') continue; /* CRLF line terminator */
- if (old == '\r') {
- if (a == '\n') break;
- else *s++ = '\r';
- }
- #endif /* NLCHAR */
- *s = a;
- s++;
- }
- *s = '\0';
- return(z);
- }
-
-
-
- /*
- * (PWP) (re)fill the buffered input buffer with data. All file
- * input should go through this routine, usually by calling the
- * zminchar() macro
- */
-
- zinfill() {
- int err;
- long rdcnt; /* pascal long */
- register MACFILE *fpp;
- char *cp;
-
- fpp = &fp[ZIFILE];
-
- /* if not an open file; just get one character */
- if (!(fpp->fstatus & FS_OPEN)) {
- zincnt = 0;
- if (zchin (ZIFILE, zinbuffer) < 0)
- return (-1);
- return (zinbuffer[0]);
- }
-
- rdcnt = INBUFSIZE;
- err = FSRead (fpp->frefnum, &rdcnt, zinbuffer);
- zincnt = rdcnt; /* set number actually read */
-
- /* check for any errors */
- if ((err != noErr) && (err != eofErr) && (!ioutil(err)))
- return (-1);
-
- /*
- * PWP: FSRead will return eofErr when it reads the last
- * partial block of data. If rdcnt > 0, then we still have
- * the last bit of the file to send out...
- */
- if (err == eofErr) {
- if (rdcnt == 0) { /* if actual EOF */
- return (-1); /* EOF return */
- } else { /* last real block */
- if (fpp->fstatus & FS_MACB) { /* if MacBinary format */
- /* pad out things */
- rdcnt = (128 - (filargs.filsiz % 128)) % 128;
-
- /* for (cp = &zinbuffer[zincnt]; rdcnt > 0; rdcnt--) */
- for (cp = zinbuffer + zincnt; rdcnt > 0; rdcnt--)
- *cp++ = 0;
-
- zincnt = (zincnt + 127) & ~127; /* pad out to 128 bytes */
-
- if (fpp->fstatus & FS_DATA) { /* if we were doing data fork */
- fpp->fstatus &= ~FS_DATA;
-
- if (filargs.rsrcsiz != 0) { /* if a resource fork */
- if ((err = FSClose (fpp->frefnum)) != noErr) {
- printerr("zinfill: trouble closing data fork:",
- err);
- return (-1);
- }
-
- /* open the resource fork 'cause we do that next */
- if ((err = OpenRF_rdonly (c2p_tmp(MBname), filargs.filvol,
- &fpp->frefnum)) != noErr) {
- printerr("zinfill: trouble opening rsrc fork:",
- err);
- return (-1);
- }
-
- /* in case anyone else needs to know */
- fpp->fstatus |= FS_RSRC;
- }
- }
- }
- }
- }
-
- zinptr = zinbuffer; /* set pointer to beginning, (== &zinbuffer[0]) */
- zincnt--; /* one less char in buffer */
- return((int)(*zinptr++) & 0377); /* because we return the first */
- }
-
-
- /****************************************************************************/
- /* Z S O U T -- Write a string to the given file, buffered.
- *
- * Returns:
- * 0: OK
- * -1: Error
- *
- */
- /****************************************************************************/
- zsout (n, s)
- int n;
- char *s;
- {
- long wrcnt; /* pascal long */
-
- if (n == ZCTERM || fp[n].fstatus == FS_WIND)
- return (conol (s));
-
- wrcnt = (long) strlen (s);
- return (ioutil (FSWrite (fp[n].frefnum, &wrcnt, s)) ? 0 : -1);
- } /* zsout */
-
-
-
- /****************************************************************************/
- /* Z S O U T L -- Write string to file, with line terminator, buffered.
- *
- * Returns:
- * 0: OK
- * -1: Error
- *
- */
- /****************************************************************************/
- zsoutl (n, s)
- int n;
- char *s;
- {
- long wrcnt; /* pascal long */
- int err;
-
- if (n == ZCTERM || fp[n].fstatus == FS_WIND)
- return (conoll (s));
-
- wrcnt = (long) strlen (s);
- err = FSWrite (fp[n].frefnum, &wrcnt, s);
- if (err == noErr) {
- wrcnt = 2;
- err = FSWrite (fp[n].frefnum, &wrcnt, "\r\n");
- }
- return (ioutil (err) ? 0 : -1);
- } /* zsoutl */
-
-
-
- /****************************************************************************/
- /* Z S O U T X -- Write x characters to file, unbuffered.
- *
- * Returns:
- * 0: OK
- * -1: Error
- */
- /****************************************************************************/
- zsoutx (n, s, x)
- int n, x;
- char *s;
- {
- long size;
-
- if (n == ZCTERM || fp[n].fstatus == FS_WIND)
- return (conxo (x, s));
-
- size = x;
- return (ioutil (FSWrite (fp[n].frefnum, &size, s)) ? 0 : -1);
- } /* zsoutx */
-
-
-
- /****************************************************************************/
- /* Z C H O U T -- Add a character to the given file. */
- /* */
- /* Returns: */
- /* 0: OK */
- /* -1: Error */
- /****************************************************************************/
- zchout (n, c)
- int n;
- char c;
- {
- long wrcnt; /* pascal long */
- int err;
-
- if (n == ZCTERM || fp[n].fstatus == FS_WIND) {
- conoc (c); /* Then send to console routine */
- return (0); /* Then send to console routine */
- }
-
- if (n == ZOFILE) /* (PWP) just in case */
- return (zmchout(c));
-
- wrcnt = 1;
- err = FSWrite (fp[n].frefnum, &wrcnt, &c);
- if (err != noErr) /* error occured? */
- sstate = 'a'; /* yes, abort protocol */
- return (ioutil (err) ? 0 : -1); /* else return code */
- } /* zchout */
-
-
- /****************************************************************************
- * (PWP) Tell the mac to actually write the contents of the file to disk.
- * this avoids the problem of the Mac waiting around until it has filled
- * the disk cache and then flushing all of it at once (which takes several
- * seconds).
- */
- void
- flush_file_in_background(int frefnum)
- {
- int err;
- ParamBlockRec info;
-
- info.ioParam.ioRefNum = frefnum; /* file descriptor */
- info.ioParam.ioCompletion = NULL; /* no completion routine to call */
-
- err = PBFlushFile (&info, TRUE); /* tell system to flush that file */
-
- if (err != noErr) /* any error? */
- printerr ("flush_file_in_background failed: ", err);
- /* tell me about it */
- }
-
-
- /* (PWP) buffered character output routine to speed up file IO */
- zoutdump()
- {
- long wrcnt, tmpcnt; /* pascal long */
- int err;
- char *outp;
-
- debug(F101," zoutdump: zoutcnt","",zoutcnt);
-
- if ((zoutcnt < 0) || (zoutcnt > OBUFSIZE)) {
- printerr("zoutdump(): zoutcnt out of range", zoutcnt);
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return (-1);
- }
-
- wrcnt = (long) zoutcnt;
- if (wrcnt <= 0)
- return (0); /* nothing to do */
-
- if (fp[ZOFILE].fstatus == FS_WIND) { /* if console output */
- conxo(zoutcnt, zoutbuffer);
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return(0);
- }
-
- outp = zoutbuffer;
-
- if (fp[ZOFILE].fstatus & FS_MACB) { /* if MacBinary format */
- /* if done with both Data and Rsrc */
- if (!(fp[ZOFILE].fstatus & FS_OPEN)) {
- /* keep track of how much leftover we got */
- zcnt_written += wrcnt;
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return (0); /* toss 'em */
- }
- /* looking for header */
- if (!(fp[ZOFILE].fstatus & (FS_RSRC | FS_DATA))) {
- if (zoutcnt < 128) /* we don't have all of the header yet */
- return (0);
-
- bcopy(zoutbuffer, &filHead, 128);
-
- if (!is_macbinary(filHead)) {
- screen(SCR_WM, 0, 0l,
- "Not a MacBinary file, reverting to binary, data fork");
- screen(SCR_AN,0,0l,MBname); /* stop saying MacBinary mode */
- err = FSOpen (c2p_tmp(MBname),
- filargs.filvol,
- &fp[ZOFILE].frefnum);
- if (err != noErr) {
- printerr("zoutdump(): trouble with FSOpen:", err);
- (void) ioutil(err);
- return (-1);
- }
- fp[ZOFILE].fstatus = FS_OPEN | FS_DATA; /* unset FS_MACB */
- goto norm_file;
- }
-
- /* adjust pointers */
- wrcnt = zoutcnt - 128;
- outp = &zoutbuffer[128];
-
- /* get the sizes from header */
- bcopy(&filHead.dflen[0], &filargs.filsiz, 4);
- bcopy(&filHead.rflen[0], &filargs.rsrcsiz, 4);
-
- if (filargs.filsiz > 0) { /* is there a data fork? */
- err = FSOpen (c2p_tmp(MBname),
- filargs.filvol, &fp[ZOFILE].frefnum);
- if (err != noErr) printerr("zoutdump(): trouble with FSOpen:",
- err);
- fp[ZOFILE].fstatus |= FS_DATA;
- } else { /* else data, or some other file */
- err = OpenRF (c2p_tmp(MBname),
- filargs.filvol, &fp[ZOFILE].frefnum);
- if (err != noErr)
- printerr("zoutdump(): trouble with OpenRF:", err);
- fp[ZOFILE].fstatus |= FS_RSRC;
- }
-
- if (err != noErr) {
- sstate = 'a'; /* yes, abort protocol */
- return (ioutil (err) ? 0 : -1);
- }
-
- zcnt_written = 0;
-
- /* screen(SCR_AN,0,0l,MBname); */ /* Make screen say MacBinary */
-
- if (wrcnt <= 0) { /* if nothing to write */
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return (0); /* we are done this time */
- }
- }
-
- /* can't be "else if" here, above if may feed this if */
- if (fp[ZOFILE].fstatus & FS_DATA) { /* if doing data fork */
- if (zcnt_written + wrcnt >= filargs.filsiz) {
- tmpcnt = wrcnt; /* save old amount of data */
-
- /* figure how how much we really should write */
- wrcnt = filargs.filsiz - zcnt_written;
- err = FSWrite (fp[ZOFILE].frefnum, &wrcnt, outp);
- zcnt_written += wrcnt;
- outp += wrcnt;
-
- wrcnt = tmpcnt - wrcnt; /* adjust to reflect the write */
-
- /* close data fork, open rsrc fork */
- if (err == noErr)
- err = FSClose (fp[ZOFILE].frefnum);
- if (err == noErr) /* and if that worked */
- err = FlushVol (NILPTR, /* flush OS buffers */
- filargs.filvol);
- if (err == noErr)
- err = OpenRF (c2p_tmp(MBname), filargs.filvol, /* yes... */
- &fp[ZOFILE].frefnum);
- if (err != noErr) { /* error occured? */
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- sstate = 'a'; /* yes, cancel protocol */
- return (ioutil (err) ? 0 : -1); /* else return code */
- }
-
- fp[ZOFILE].fstatus &= ~FS_DATA;
- fp[ZOFILE].fstatus |= FS_RSRC;
-
- /*
- * tmpcnt is now the amount of extra buffer characters we
- * need to see in order to fill out this 128 byte "block".
- */
- tmpcnt = ((zcnt_written + 127) & ~127) - zcnt_written;
- if (wrcnt < tmpcnt) {
- /* mark more padding still needed */
- zcnt_written = -tmpcnt + wrcnt;
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return (0); /* we are done this time */
- }
-
- /* all the padding is here -- skip over it */
- wrcnt -= tmpcnt;
- outp += tmpcnt;
- zcnt_written = 0; /* reset for RSRC fork */
- /* fall through to RSRC fork if(), below... */
- }
- }
-
- /*
- * Also can't be "else if" here, because above if just might
- * feed this if too.
- */
- if (fp[ZOFILE].fstatus & FS_RSRC) { /* if doing data fork */
- if (zcnt_written < 0) { /* if we need to skip more padding */
- outp += -zcnt_written;
- wrcnt -= -zcnt_written;
- zcnt_written = 0;
- }
- if (zcnt_written + wrcnt >= filargs.rsrcsiz) {
- tmpcnt = wrcnt; /* save old amount of data */
-
- /* figure how how much we really should write */
- wrcnt = filargs.rsrcsiz - zcnt_written;
- err = FSWrite (fp[ZOFILE].frefnum, &wrcnt, outp);
- zcnt_written += wrcnt;
- outp += wrcnt;
-
- wrcnt = tmpcnt - wrcnt; /* adjust to reflect the write */
-
- /* close rsrc fork, set flags to toss output */
- if (err == noErr)
- err = FSClose (fp[ZOFILE].frefnum);
- if (err == noErr) /* and if that worked */
- err = FlushVol (NILPTR, /* flush OS buffers */
- filargs.filvol);
- if (err != noErr) { /* error occured? */
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- sstate = 'a'; /* yes, abort protocol */
- return (ioutil (err) ? 0 : -1); /* else return code */
- }
-
- /* say this file is no longer open */
- fp[ZOFILE].fstatus &= ~(FS_OPEN | FS_DATA | FS_RSRC);
-
- zcnt_written += wrcnt; /* we keep track of leftovers */
-
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return (0); /* we are done this time */
- }
- }
- }
- norm_file:
- debug(F101," zoutdump: normal file, writing","",wrcnt);
-
- err = FSWrite (fp[ZOFILE].frefnum, &wrcnt, outp);
- debug(F101," zoutdump: FSWrite returned","",err);
- debug(F101," zoutdump: wrote","",wrcnt);
- zcnt_written += wrcnt;
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- if (err != noErr) { /* error occured? */
- sstate = 'a'; /* yes, abort protocol */
- return (ioutil (err) ? 0 : -1); /* else return code */
- }
- flush_file_in_background(fp[ZOFILE].frefnum);
- return (0); /* no problems */
- }
-
- /****************************************************************************/
- /* C H K F N -- Internal function to verify file number is ok.
- *
- * Returns:
- * TRUE - file is open
- * FALSE - file is not open
- *
- * Issues an error message if the file number is not in range.
- *
- */
- /****************************************************************************/
- chkfn (n)
- int n;
- {
- if (n < ZNFILS)
- return ((fp[n].fstatus != 0)); /* if open, fstatus is nonzero */
-
- debug (F101, "chkfn: file number out of range", "", n);
- printerr ("chkfn - file number not in range: ", n);
- return (FALSE); /* ugh */
- } /* chkfn */
-
-
-
- /****************************************************************************/
- /* Z C H K I -- Check if input file exists and is readable.
- *
- * Returns:
- * >= 0 if the file can be read (returns the size).
- * -1 if file doesn't exist or can't be accessed,
- * -2 if file exists but is not readable (e.g. a directory file).
- * -3 if file exists but protected against read access.
- */
- /****************************************************************************/
- long
- zchki (name)
- char *name;
- {
- int err;
- ParamBlockRec info;
-
- if (strcmp (name, "stdin") == 0) /* stdin is a pipe */
- return (PIPESIZE); /* return size of buffer */
-
- c2pstr (name); /* convert to a pascal string */
- info.fileParam.ioFVersNum = 0; /* No version number */
- info.fileParam.ioFDirIndex = 0; /* Use the file name */
- info.fileParam.ioNamePtr = name; /* Point to the file name */
- info.fileParam.ioVRefNum = filargs.filvol; /* Volume number */
- err = PBGetFInfo (&info, FALSE); /* Get info on file */
- p2cstr (name); /* put the name back */
-
- if (err == fnfErr) /* file not found? */
- return (-1); /* then that is what they want */
-
- if (err != noErr) { /* any other error? */
- printerr ("zchki failed: ", err); /* tell me about it */
- return (-1);
- }
-
- /* if we are doing MacBinary format transfer */
- if ((filargs.filflg & (FIL_RSRC|FIL_DATA)) == (FIL_RSRC|FIL_DATA)) {
- /*
- * MacBinary size is:
- * 128 byte header
- * + data fork, rounded up to the next 128 boundry
- * + resource fork, rounded up to the next 128 boundry
- */
- iflen = ((info.fileParam.ioFlLgLen + 127) & ~127)
- + ((info.fileParam.ioFlRLgLen + 127) & ~127)
- + 128;
- } else {
- /* normal (non-MacBinary) file */
- iflen = (filargs.filflg & FIL_RSRC) ? /* if thinking about RSRC */
- info.fileParam.ioFlRLgLen : /* return that size, */
- info.fileParam.ioFlLgLen; /* else DATA */
- }
-
- return (iflen); /* did ok */
- } /* zchki */
-
-
-
- /****************************************************************************/
- /* Z C H K O -- Check if output file can be created.
- *
- * Returns
- * 0: Write OK
- * -1: write permission for the file should be denied.
- */
- /****************************************************************************/
- zchko (name)
- char *name; /* unused in this */
- {
- Str255 volname;
- ParamBlockRec info;
-
- info.volumeParam.ioVolIndex = 0; /* Use the vol ref num only */
- info.volumeParam.ioNamePtr = &volname; /* Pointer to the volume name */
- info.volumeParam.ioVRefNum = filargs.filvol; /* Volume reference number */
- if (!ioutil (PBGetVInfo (&info, 0))) /* Get info on vol, synchronously */
- return (-1); /* failed... */
-
- if ((info.volumeParam.ioVAtrb & 0x8000) != 0) /* Write locked? */
- return (-1); /* yes... */
-
- return (0); /* else success */
- } /* zchko */
-
-
-
- /****************************************************************************/
- /* Z D E L E T -- Delete the named file and return TRUE if successful */
- /****************************************************************************/
- int
- zdelet (name) char *name; {
- int err;
- err = remove(name);
- debug(F101,"zdelet","",err);
- return(err == 0 ? 0 : -1);
- }
-
-
-
- /****************************************************************************/
- /* Z R T O L -- Convert remote filename into local form.
- *
- * Check here to see if this should go into the resource fork (.rsrc)
- * or into the data fork (.data).
- *
- */
- /****************************************************************************/
- VOID zrtol (name, name2)
- char *name, *name2;
- {
-
- strcpy (name2, name); /* copy name to destination */
-
- if (filargs.filflg & (FIL_DODLG)) /* selected by user? */
- return; /* won't be called but... */
-
- filargs.filflg &= ~(FIL_RBDT); /* clear out flags */
- filargs.filflg |= sfprtol (name2); /* convert name2 and set flags */
- binary = (filargs.filflg & FIL_BINA); /* selected binary mode? */
- return;
- } /* zrtol */
-
- /****************************************************************************/
- /* Z S T R I P -- Strip device & directory name from file specification */
- /****************************************************************************/
-
- /* Strip pathname from filename "name", return pointer to result in name2 */
-
- static char work[100]; /* buffer for use by zstrip */
-
- VOID
- zstrip(name,name2) char *name, **name2; {
- char *cp, *pp;
- debug(F110,"zstrip before",name,0);
- pp = work;
- for (cp = name; *cp != '\0'; cp++) {
- if (*cp == ':')
- pp = work;
- else
- *pp++ = *cp;
- }
- *pp = '\0'; /* Terminate the string */
- *name2 = work;
- debug(F110,"zstrip after",*name2,0);
- }
-
- /****************************************************************************/
- /* Z L T O R -- Convert filename from local format to common form. */
- /****************************************************************************/
- void zltor(name, name2) char *name, *name2; {
- int dc = 0; /* Dot counter */
- char c; /* For each character from name */
- char *pp; /* Pointer to work buffer */
-
- pp = work; /* Point to start of work buffer */
-
- while ((c = *name++) != '\0') { /* Go thru original name */
- if (c == ' ') /* Change space to underscore */
- *pp++ = '_';
- else if (c == ':') /* Colon is the directory seperator */
- pp = work; /* Strip pathname */
- else if ((c == '.') && (++dc > 1))
- *pp++ = 'X'; /* Just 1 dot allowed */
- else /* Convert letters to uppercase */
- *pp++ = (islower(c)) ? toupper(c) : c;
- }
- *pp = '\0'; /* Deposit final null */
- pp = work; /* Back to beginning of work buffer */
- if (*pp == '.') /* If it starts with a dot, */
- *name2++ = 'X'; /* insert an X. */
- strcpy(name2,work); /* Copy result to destination. */
- if (strlen(name2) == 0) /* Make sure something is there. */
- strcpy(name2,"X");
- debug(F110," name2",name2,0); /* (debug) */
- return;
- } /* zltor */
-
- static char *mgbufp = NULL;
- extern char *malloc();
-
- #ifndef NOMSEND /* Multiple SEND */
- #define MSENDMAX 100
- char *msfiles[MSENDMAX];
- #endif
-
- /* F N P A R S E -- */
-
- /*
- Argument is a character string containing one or more filespecs.
- This function breaks the string apart into an array of pointers, one
- to each filespec, and returns the number of filespecs. Used by server
- when it receives a GET command to allow it to process multiple file
- specifications in one transaction. Sets cmlist to point to a list of
- file pointers, exactly as if they were command line arguments.
-
- This version of fnparse treats spaces as filename separators. If your
- operating system allows spaces in filenames, you'll need a different
- separator.
-
- This version of fnparse mallocs a string buffer to contain the names. It
- cannot assume that the string that is pointed to by the argument is safe.
- */
- #ifdef MAC /* Filename separator */
- #define FNSEP ','
- #else
- #define FNSEP SP
- #endif
- fnparse(string) char *string; {
- char *p, *s;
- int r = 0; /* Return code */
- extern char **cmlist;
-
- if (mgbufp) free(mgbufp); /* Free this from last time. */
- mgbufp = malloc(strlen(string)+2);
- if (!mgbufp) {
- debug(F100,"fnparse malloc error","",0);
- return(0);
- }
- strcpy(mgbufp,string); /* Make a safe copy */
- p = s = mgbufp; /* Point to the copy */
- r = 0; /* Initialize our return code */
- while (*p == SP) p++,s++; /* Skip leading spaces */
- while (1) { /* Loop through rest of string */
- if (*s == FNSEP || *s == NUL) { /* Look for separator or terminator */
- msfiles[r] = p; /* Add this filename to the list */
- debug(F111,"fnparse",msfiles[r],r);
- r++; /* Count it */
- if (*s == NUL) break; /* End of string? */
- *s++ = NUL; /* No, turn space to NUL */
- while (*s == SP) s++; /* Skip repeated spaces */
- p = s; /* Start of next name */
- continue;
- }
- s++; /* Otherwise keep scanning */
- }
- debug(F101,"fnparse r","",r);
- cmlist = msfiles;
- return(r);
- }
-
-
- /****************************************************************************/
- /* Z C H K S P A -- Check if there is enough space to store the file */
- /****************************************************************************/
-
- /*
- Call with file specification f, size n in bytes.
- Returns -1 on error, 0 if not enough space, 1 if enough space.
- */
- zchkspa(f,n) char *f; long n; { /* $$$ Just dummy for now. */
- return(1); /* Always say OK. */
- }
-
-
- /****************************************************************************/
- /* Z R E N A M E -- Rename a file */
- /****************************************************************************/
-
- /* Call with old and new names */
- /* Returns 0 on success, -1 on failure. */
-
- int
- zrename(old,new) char *old, *new; {
- int err;
- err = rename(old,new);
- debug(F101,"zrenam","",err);
- return(err == 0 ? 0 : -1);
- }
-
-
- /****************************************************************************/
- /* Z C H D I R -- Change directory or volumes */
- /****************************************************************************/
- int
- zchdir (dirnam) char *dirnam; {
- int err;
- int volnum;
- WDPBRec vinfo;
- short *FSFCBLen = (short *)0x3F6;
-
- if (*FSFCBLen < 0) { /* if no HFS ROM's */
- err = SetVol (c2p_tmp(dirnam), 0);
- volnum = 0;
- } else { /* use HFS calls */
- c2pstr (dirnam);
- vinfo.ioVRefNum = 0; /* open a workimg directory */
- vinfo.ioWDDirID = 0;
- vinfo.ioWDProcID = 'ERIK';
- vinfo.ioNamePtr = dirnam;
- err = PBOpenWD (&vinfo, FALSE);
- p2cstr (dirnam);
- if (err != noErr)
- return (FALSE);
-
- err = SetVol (NIL, vinfo.ioVRefNum);
- volnum = vinfo.ioVRefNum;
- }
- #ifdef COMMENT
- /*
- Don't write to screen!
- */
- if (err == noErr) { /* set default volume */
- screen (SCR_TN, 0, 0l, dirnam);
- filargs.filvol = volnum; /* make default */
- } else
- screen (SCR_TN, 0, 0l, "Can't set directory");
- #else
- if (err == noErr) { /* set default volume */
- filargs.filvol = volnum; /* make default */
- }
- #endif /* COMMENT */
- return (err == noErr); /* return ok or fail */
- } /* zchdir */
-
- /****************************************************************************/
- /* Z H O M E -- Return pointer to user's home directory */
- /****************************************************************************/
- /*
- This one should return the name of the boot volume.
- */
- char *
- zhome() {
- return("(directory unknown)"); /* PWP: for now */
- }
-
- /****************************************************************************/
- /* Z G T D I R -- Return pointer to user's current directory */
- /****************************************************************************/
- /*
- This one should
- */
- char *
- zgtdir() {
- return ("(directory unknown)"); /* PWP: for now */
- }
-
- /****************************************************************************/
- /* initialize the fields of a pipe */
- /****************************************************************************/
- zinitpipe (pipe, refillproc)
- MACPIPE *pipe;
- ProcPtr refillproc;
- {
- pipe->refill = refillproc;
- pipe->currptr = pipe->pipebuf;
- pipe->charsleft = 0;
- *(pipe->currptr) = '\0';
- } /* zinitpipe */
-
-
-
- /****************************************************************************/
- /* fill the pipe; last is TRUE if it is the */
- /* last time the pipe has to be filled */
- /****************************************************************************/
- zfillpipe (pipe, str, last)
- MACPIPE *pipe;
- char *str;
- Boolean last;
- {
- int len;
-
- len = strlen (str);
- if (last)
- len++;
-
- if (len > PIPESIZE) {
- len = PIPESIZE;
- if (last)
- str[PIPESIZE - 1] = '\0'; /* make sure we keep the eop
- * character */
- printerr ("pipe overflow! characters may be lost", 0);
- }
- memcpy (pipe->pipebuf, str, len);
- pipe->charsleft = len;
- } /* zfillpipe */
-
-
-
- /****************************************************************************/
- /* sprintf uses 12 kByte. This is the reason to use a simpler formatter here */
- /* formatnum returns a right adjusted numberstring padded with fillc */
- /* Numbers which do not fit into width are truncated on the left. */
- /* Make sure str is at least 'width+1' bytes wide */
- /****************************************************************************/
- formatnum (num, fillc, width, str)
- char *str;
- long num;
- char fillc;
- int width;
- {
- int i;
- char numstr[12]; /* -2147483647 is the longest string */
- /* that can be returned from NumToString */
-
- NumToString (num, numstr);
- p2cstr(numstr);
- i = strlen (numstr);
-
- while ((i >= 0) && (width >= 0))
- str[width--] = numstr[i--];
-
- while (width >= 0)
- str[width--] = fillc;
- } /* formatnum */
-
-
-
- MACPIPE cmdpipe;
-
- int volindex;
- char spaceheader[60] = "\
- Free Name\n\
- --------- --------------------\n";
-
- /****************************************************************************/
- /* loop through all available volumes and display the space left */
- /****************************************************************************/
- zlspace ()
- {
- int err;
- Str255 name;
- long free;
- char outstr[60];
- ParamBlockRec vinfo;
-
- name[0] = 0; /* name.length = 0; */
- vinfo.volumeParam.ioVolIndex = volindex;
- vinfo.volumeParam.ioNamePtr = &name;
- err = PBGetVInfo (&vinfo, FALSE);
-
- if (err == noErr) {
- free = vinfo.volumeParam.ioVFrBlk * vinfo.volumeParam.ioVAlBlkSiz;
- formatnum (free, ' ', 9, outstr);
- strcat (outstr, " ");
- p2cstr (&name);
- strcat (outstr, &name);
- strcat (outstr, "\n");
- zfillpipe (&cmdpipe, outstr, FALSE);
- volindex++;
- } else
- zfillpipe (&cmdpipe, "", TRUE);
-
- } /* zlspace */
-
-
-
- int fileindex;
- char dirheader[100] = "\
- Size Type Crea Last Modification Name\n\
- ------- ---- ---- ----------------- --------------------\n";
-
- /****************************************************************************/
- /* loop through all the files on the current volume / directory */
- /****************************************************************************/
- zldir ()
- {
- int err;
- CInfoPBRec info;
- WDPBRec vinfo;
-
- Str255 name;
- DateTimeRec dtrec;
-
- char outstr[60];
- char type[10];
- char tmpstr[11];
- char datestr[11];
- char hourstr[3];
- char minutestr[3];
-
- unsigned long secs;
- long size;
-
- short *FSFCBLen = (short *) 0x3F6;
-
- if (*FSFCBLen < 0) {
- /* errpkt ("Sorry, the server uses 64 kByte ROM's"); */
- errpkt ("Sorry, the server is not running on an HFS disk"); /* $$$ */
- zfillpipe (&cmdpipe, "", TRUE);
- return;
- }
- PBHGetVol (&vinfo, FALSE);
-
- /* loop through all the files starting at the first one */
- name[0] = 0; /* name.length = 0; */
- info.hfileInfo.ioFDirIndex = fileindex; /* Get next file name */
- info.hfileInfo.ioNamePtr = &name; /* Point to the empty file name */
- info.hfileInfo.ioVRefNum = vinfo.ioWDVRefNum; /* Directory / Volume
- * number */
- info.hfileInfo.ioDirID = vinfo.ioWDDirID; /* Directory / Volume number */
- err = PBGetCatInfo (&info, FALSE); /* Get info on file */
-
- if (err == noErr) {
- if (info.hfileInfo.ioFlAttrib & ioDirMask) { /* a directory if it's
- * true */
- secs = info.dirInfo.ioDrMdDat;
- strcpy (type, "#########");
- strcpy (outstr, " ");
- } else { /* a file otherwise */
- secs = info.hfileInfo.ioFlMdDat;
- size = info.hfileInfo.ioFlLgLen + info.hfileInfo.ioFlRLgLen;
- strcpy (type, " ");
- memcpy (type, &info.hfileInfo.ioFlFndrInfo.fdType, 4);
- memcpy (type + 5, &info.hfileInfo.ioFlFndrInfo.fdCreator, 4);
- formatnum (size, ' ', 7, outstr);
- }
- IUDateString (secs, shortDate, tmpstr);
- p2cstr(tmpstr);
- strcpy (datestr, " ");
- datestr[10 - strlen (tmpstr)] = '\0';
- strcat (datestr, tmpstr);
-
- Secs2Date (secs, &dtrec);
- formatnum (dtrec.hour, ' ', 2, hourstr);
- formatnum (dtrec.minute, '0', 2, minutestr);
-
- p2cstr (&name);
-
- strcat (outstr, " ");
- strcat (outstr, type);
- strcat (outstr, " ");
- strcat (outstr, datestr);
- strcat (outstr, " ");
- strcat (outstr, hourstr);
- strcat (outstr, ":");
- strcat (outstr, minutestr);
- strcat (outstr, " ");
- strcat (outstr, &name);
- strcat (outstr, "\n");
-
- zfillpipe (&cmdpipe, outstr, FALSE);
- fileindex++;
- } else
- zfillpipe (&cmdpipe, "", TRUE);
-
- } /* zldir */
-
-
-
- #define CMD_RSRC 1
- #define CMD_DATA 2
- #define CMD_TEXT 3
- #define CMD_BINA 4
- #define CMD_DIR 5
- #define CMD_DEL 6
- #define CMD_SPC 7
- #define CMD_UNK 255
-
- char *cmdtab[] = {
- "fork rsrc",
- "fork data",
- "mode binary",
- "mode text",
- DIRCMDSTR,
- DELCMDSTR,
- SPCCMDSTR
- };
-
- int toktab[] = {
- CMD_RSRC,
- CMD_DATA,
- CMD_BINA,
- CMD_TEXT,
- CMD_DIR,
- CMD_DEL,
- CMD_SPC
- };
-
- #define NTOKS (sizeof (toktab)/sizeof(int))
-
- /****************************************************************************/
- /* Z X C M D -- Run a system command so its output can be read like a file.
- *
- * Used on the MAC to implement MAC settings commands -- commands from a
- * remote system when in server mode that change internal variables.
- *
- */
- /****************************************************************************/
- int
- zmxcmd (comand)
- char *comand;
- {
- int sc;
- char theStr[120];
- int retCd;
-
- fp[ZIFILE].fstatus = FS_PIPE; /* set input from pipe */
- fp[ZIFILE].fpipe = &cmdpipe;/* init pointer to command pipe */
-
- switch (sc = getcmd (comand)) {
- case CMD_RSRC:
- case CMD_DATA:
- zinitpipe (&cmdpipe, NILPROC);
- zfillpipe (&cmdpipe, "Default Fork set OK\n", TRUE);
- filargs.filflg &= ~(FIL_RSRC | FIL_DATA); /* turn off */
- filargs.filflg |= (sc == CMD_RSRC) ? FIL_RSRC : FIL_DATA;
- return (TRUE); /* ok */
-
- case CMD_TEXT:
- case CMD_BINA:
- zinitpipe (&cmdpipe, NILPROC);
- zfillpipe (&cmdpipe, "Default Mode set OK\n", TRUE);
- filargs.filflg &= ~(FIL_TEXT | FIL_BINA);
- filargs.filflg |= (sc == CMD_BINA) ? FIL_BINA : FIL_TEXT;
- return (TRUE); /* ok */
-
- case CMD_DIR:
- zinitpipe (&cmdpipe, zldir);
- zfillpipe (&cmdpipe, dirheader, FALSE);
- fileindex = 1; /* start at the first file on */
- /* the current volume / directory */
- return (TRUE); /* always ok */
-
- case CMD_DEL:
- strcpy (theStr, comand + strlen (DELCMDSTR)); /* the filename
- * immediately */
- retCd = zdelet (theStr);/* follows the command name */
- if (retCd) {
- zinitpipe (&cmdpipe, NILPROC);
- strcat (theStr, " deleted.");
- zfillpipe (&cmdpipe, theStr, true);
- }
- return (retCd);
-
- case CMD_SPC:
- zinitpipe (&cmdpipe, zlspace); /* init pipe for space listing */
- zfillpipe (&cmdpipe, spaceheader, FALSE); /* copy the header to
- * the pipe */
- volindex = 1; /* start with the first volume */
- return (TRUE); /* always ok */
-
- default:
- return (FALSE); /* fail, unknown */
- }
- } /* zxcmd */
-
-
- /*
- * zxcmd
- * Temporary so we can link correctly.
- */
- zxcmd(filnum,comand)
- int filnum;
- char *comand;
- {
- printerr("MAC zxcmd called", 0);
- return 0;
- }
-
-
- /****************************************************************************/
- /****************************************************************************/
- getcmd (cmd)
- char *cmd;
- {
- int k;
-
- for (k = 0; k < NTOKS; k++)
- if (strncmp (cmdtab[k], cmd, strlen (cmdtab[k])) == 0)
- return (toktab[k]); /* and return ID */
- return (CMD_UNK); /* else unknown */
-
- } /* getcmd */
-
-
-
- /****************************************************************************/
- /* Z C L O S F - wait for the child fork to terminate and close the pipe. */
- /****************************************************************************/
- zclosf ()
- {
- return;
- } /* zclosf */
-
-
-
- int zindex;
- int zfiles;
- char *zname;
- static char znm_storage[64];
-
- /****************************************************************************/
- /* Z X P A N D -- Expand a wildcard string into an array of strings
- *
- * Returns the number of files that match fn, with data structures set up
- * so that first file (if any) will be returned by the next znext() call.
- */
- /****************************************************************************/
- zxpand (fn)
- char *fn;
- {
- int err;
- ParamBlockRec info;
-
- zfiles = 1;
-
- debug(F110," zxpand fn",fn, 0);
-
- if ((filargs.filflg & FIL_ALLFL) || /* all files check box on or */
- (strcmp (fn, ":") == 0)) { /* server 'get' with filname = ':' */
-
- /* the ioVNmFls field of the VolumeParam returns the number of files */
-
- /*
- * !and! directories after PBGetInfo. This is why we have to count
- * here.
- */
-
- info.fileParam.ioFVersNum = 0; /* No version number */
- info.fileParam.ioNamePtr = NIL; /* Point to the file name */
- info.fileParam.ioVRefNum = filargs.filvol; /* Volume number */
- do {
- info.fileParam.ioFDirIndex = zfiles; /* Get next file name */
- err = PBGetFInfo (&info, FALSE); /* Get info on file */
- zfiles++;
- } while (err == noErr);
- zname = NIL; /* no specific file */
- zfiles -= 2; /* we counted 2 too high */
-
- } else {
-
- strncpy(znm_storage, fn, 63); /* copy fn to local storage */
- znm_storage[63] = '\0'; /* string paranoia */
- zname = znm_storage; /* keep a pointer to that name */
- }
-
- zindex = 0; /* init the files sent counter */
- return (zfiles);
- } /* zxpand */
-
-
-
- /****************************************************************************/
- /* Z N E X T -- Get name of next file from list created by zxpand().
- *
- * Returns >0 if there's another file, with its name copied into the
- * arg string, or 0 if no more files in list.
- */
- /****************************************************************************/
- znext (fn)
- char *fn;
- {
- int err;
- Str255 name;
- ParamBlockRec info;
-
- zindex++; /* next file */
-
- if (zindex > zfiles)
- return (0); /* no more files */
-
- if (zname != NIL)
- strcpy (fn, zname); /* Get the file's name */
- else {
- info.fileParam.ioFVersNum = 0; /* No version number */
- info.fileParam.ioFDirIndex = zindex; /* Get next file name */
- info.fileParam.ioNamePtr = &name; /* Point to the file name */
- /* VolRefNum of the selected folder */
- info.fileParam.ioVRefNum = filargs.filvol;
- err = PBGetFInfo (&info, FALSE); /* Get info on file */
- if (err == noErr) {
- p2cstr (&name);
- strcpy (fn, &name); /* Return the file's name */
- *filargs.filrem = '\0'; /* reset remote name for folder
- * transfer */
- } else {
- printerr ("Error on reading next file name: ", err);
- return (0);
- }
- }
- return (1); /* fn contains the next file */
- } /* znext */
-
-
-
- /****************************************************************************/
- /* Z N E W N -- Make a new name for the given file */
- /****************************************************************************/
- VOID
- znewn (fn, s) char *fn, **s; {
- char *extp, *tmpnam(char *);
- int ver;
- static char buf[70]; /* Enough for a Mac filename */
- char *p;
-
- p = buf;
- strncpy(p, fn, 59); /* copy in the name, no long names! */
- extp = p + strlen(p); /* find position of extension */
- *extp++ = '.'; /* add in the dot now */
-
- for (ver = 0; ver < 99; ver++) { /* I'll try this many names */
- NumToString ((long) ver, extp); /* add in the number */
- p2cstr(extp);
- if (zchki(p) == -1) { /* is this file known? */
- *s = buf; /* no, we can use this name. */
- return;
- }
- }
- p = buf; /* Failed, use tmpnam(). */
- *s = tmpnam(p);
- return;
- } /* znewn */
-
- /* I S W I L D */
- /*
- * return true (1) if the file spec contains any Kermit wild cards
- */
-
- iswild(filespec) char *filespec; {
- return (0); /* MacKermit doesn't do wild cards yet */
- }
-
-
- /* Z S A T T R */
- /*
- Fills in a Kermit file attribute structure for the file which is to be sent.
- Returns 0 on success with the structure filled in, or -1 on failure.
- If any string member is null, then it should be ignored.
- If any numeric member is -1, then it should be ignored.
- */
- zsattr(xx) struct zattr *xx; {
- long k;
-
- k = iflen % 1024L; /* File length in K */
- if (k != 0L) k = 1L;
- xx->lengthk = (iflen / 1024L) + k;
- xx->type.len = 0; /* File type can't be filled in here */
- xx->type.val = "";
- xx->date.len = 0; /* File creation date */
- xx->date.val = "";
- xx->creator.len = 0; /* File creator */
- xx->creator.val = "";
- xx->account.len = 0; /* File account */
- xx->account.val = "";
- xx->area.len = 0; /* File area */
- xx->area.val = "";
- xx->passwd.len = 0; /* Area password */
- xx->passwd.val = "";
- xx->blksize = -1L; /* File blocksize */
- xx->access.len = 0; /* File access */
- xx->access.val = "";
- xx->encoding.len = 0; /* Transfer syntax */
- xx->encoding.val = 0;
- xx->disp.len = 0; /* Disposition upon arrival */
- xx->disp.val = "";
- xx->lprotect.len = 0; /* Local protection */
- xx->lprotect.val = "";
- xx->gprotect.len = 0; /* Generic protection */
- xx->gprotect.val = "";
- xx->systemid.len = 2; /* System ID */
- xx->systemid.val = "A3"; /* (A3: Apple Macintosh) */
- xx->recfm.len = 0; /* Record format */
- xx->recfm.val = "";
- xx->sysparam.len = 0; /* System-dependent parameters */
- xx->sysparam.val = "";
- xx->length = iflen; /* Length */
- return(0);
- }
-
- /* Find initialization file. */
-
- zkermini() {
- /* nothing yet... this function added for benefit of VMS Kermit. */
- return(0);
- }
-
- /****************************************************************************/
- pascal void
- reset ()
- /****************************************************************************/
- extern 0x4E70;
-
- /****************************************************************************/
- /* zkself() - Kill self (reboot). On other machines does a logout.
- * Flush volumes and reboot. Called by remote BYE.
- *
- */
- /****************************************************************************/
- zkself ()
- {
- DrvQEl *drvqe;
- Str255 vname;
- long vfreeb;
- short vrefnum;
- int err;
-
- /* handle on drive q */
- for (drvqe = (DrvQEl *) ((QHdr *) GetDrvQHdr ())->qHead;
- drvqe != NULL; /* while still something */
- drvqe = (DrvQEl *) drvqe->qLink) { /* step to next for each drive */
- err = GetVInfo (drvqe->dQDrive, &vname, &vrefnum, &vfreeb);
- if (err == noErr)
- err = FlushVol (NILPTR, vrefnum); /* flush the volume given
- * refnum */
- else if (err != nsvErr)
- screen (SCR_TN,0,0l,"Remote cmd: GetVinfo returned unknown code");
- }
-
- doclean (); /* clean up before leaving */
-
- doexit(GOOD_EXIT, -1);
- } /* zkself */
-
- char optbuf[50]; /* used for MAIL and REMOTE PRINT options */
-
- zmail(p,f) char *p; char *f; { /* Send file f as mail to address p */
- screen (SCR_WM,0,0l,"There is no mail support in Mac Kermit.");
- }
-
- zprint(p,f) char *p; char *f; { /* Print file f with options p */
- screen (SCR_WM,0,0l,"There is no printer support in Mac Kermit yet.");
- }
-
- struct {
- int errnum;
- char *errstr;
- } ioerrs[] = {
-
- {
- dirFulErr, "Directory is full"
- },
- {
- dskFulErr, "Disk is full"
- },
- {
- wPrErr, "Diskette is write protected"
- },
- {
- fLckdErr, "File is software locked"
- },
- {
- vLckdErr, "Volume is software locked"
- },
- {
- fBsyErr, "File is busy"
- },
- {
- opWrErr, "File is already open with write permission"
- },
- {
- fnfErr, "File does not exist"
- },
- {
- 0, NILPTR
- }
- };
-
- /****************************************************************************/
- /* ioutil - handle the result from an IO call, checking for an
- * error return and displaying an appropriate error
- * message. Returns TRUE if no error occured, FALSE
- * otherwise.
- */
- /****************************************************************************/
- int
- ioutil (err)
- int err;
- {
- int e;
-
- if (err == noErr)
- return (TRUE);
-
- for (e = 0; ioerrs[e].errnum != 0 && ioerrs[e].errnum != err; e++);
-
- if (ioerrs[e].errstr == NILPTR) /* anything there? */
- printerr ("Unknown IO error: ", err);
- else
- printerr (ioerrs[e].errstr, 0);
-
- return (FALSE);
- } /* ioutil */
-
-
- /****************************************************************************
- * OpenRF_rdonly() -- An interface just like OpenRF, but open for read only.
- ****************************************************************************/
- OSErr
- OpenRF_rdonly (char *fileName, short vRefNum, short *refNum)
- {
- ParamBlockRec pb;
-
- if (!fileName)
- DebugStr("\pfileName == NULL");
- if (!refNum)
- DebugStr("\prefNum == NULL");
-
- pb.ioParam.ioCompletion = (ProcPtr) 0;
- pb.ioParam.ioNamePtr = fileName;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioVersNum = 0;
- pb.ioParam.ioPermssn = fsRdPerm;
- pb.ioParam.ioMisc = (Ptr) 0;
- PBOpenRF (&pb, 0);
- *refNum = pb.ioParam.ioRefNum;
- return pb.ioParam.ioResult;
- } /* OpenRF_rdonly */
-
-
- /****************************************************************************
- * FSOpen_rdonly() -- An interface just like FSOpen, but open for read only.
- ****************************************************************************/
- OSErr
- FSOpen_rdonly (char *fileName, short vRefNum, short *refNum)
- {
- ParamBlockRec pb;
-
- if (!fileName)
- DebugStr("\pfileName == NULL");
- if (!refNum)
- DebugStr("\prefNum == NULL");
-
- pb.ioParam.ioCompletion = (ProcPtr) 0;
- pb.ioParam.ioNamePtr = fileName;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioVersNum = 0;
- pb.ioParam.ioPermssn = fsRdPerm;
- pb.ioParam.ioMisc = (Ptr) 0;
- PBOpen (&pb, 0);
- *refNum = pb.ioParam.ioRefNum;
- return pb.ioParam.ioResult;
- } /* FSOpen_rdonly */
-
-
-
-
- extern short dfltVol;
-
- short tlogfile;
- char tlogname[] = "Kermit Transaction";
-
- /****************************************************************************/
- /****************************************************************************/
- opentlog ()
- {
- return (openlogfile("Transaction log name:", tlogname, &tlogfile, ZTFILE));
- }
-
- /****************************************************************************/
- /****************************************************************************/
- closetlog ()
- {
- FSClose (tlogfile);
- FlushVol (NIL, dfltVol);
- } /* closetlog */
-
-
- #ifdef COMMENT
- /****************************************************************************/
- /****************************************************************************/
- tlog (f, s1, s2, n)
- int f; /* unused */
- long n;
- char *s1;
- char *s2;
- {
- char numstr[12];
- char outstr[256];
- long count;
-
- if (tralog) {
- strcpy (outstr, s1);
-
- if (strlen (s2)) {
- strcat (outstr, " ");
- strcat (outstr, s2);
- }
- if (n) {
- NumToString (n, numstr);
- p2cstr(numstr);
- strcat (outstr, " ");
- strcat (outstr, numstr);
- }
- strcat (outstr, "\r");
-
- count = strlen (outstr);
- FSWrite (tlogfile, &count, outstr);
- }
- } /* tlog */
- #endif /* COMMENT */
-
- /****************************************************************************/
- #ifdef TLOG
- #define TBUFL 300
- /* T L O G -- Log a record in the transaction file */
- /*
- Call with a format and 3 arguments: two strings and a number:
- f - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
- s1,s2 - String arguments 1 and 2.
- n - Int, argument 3.
- */
- VOID tlog(f,s1,s2,n) int f; long n; char *s1, *s2; {
- char s[TBUFL];
- char *sp = s; int x;
-
- if (!tralog) return; /* If no transaction log, don't */
- switch (f) {
- case F000: /* 0 (special) "s1 n s2" */
- if (strlen(s1) + strlen(s2) + 15 > TBUFL)
- sprintf(sp,"?T-Log string too long\r");
- else sprintf(sp,"%s %ld %s\r",s1,n,s2);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- break;
- case F001: /* 1, " n" */
- sprintf(sp," %ld\r",n);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- break;
- case F010: /* 2, "[s2]" */
- x = strlen(s2);
- if (s2[x] == '\n' || s2[x] == '\r') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?T-Log string too long\r");
- else sprintf(sp,"[%s]\r",s2);
- if (zsout(ZTFILE,"") < 0) tralog = 0;
- break;
- case F011: /* 3, "[s2] n" */
- x = strlen(s2);
- if (s2[x] == '\n' || s2[x] == '\r') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?T-Log string too long\r");
- else sprintf(sp,"[%s] %ld\r",s2,n);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- break;
- case F100: /* 4, "s1" */
- if (zsoutl(ZTFILE,s1) < 0) tralog = 0;
- break;
- case F101: /* 5, "s1: n" */
- if (strlen(s1) + 15 > TBUFL)
- sprintf(sp,"?T-Log string too long\r");
- else sprintf(sp,"%s: %ld\r",s1,n);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- break;
- case F110: /* 6, "s1 s2" */
- x = strlen(s2);
- if (s2[x] == '\n' || s2[x] == '\r') s2[x] = '\0';
- if (strlen(s1) + x + 4 > TBUFL)
- sprintf(sp,"?T-Log string too long\r");
- else sprintf(sp,"%s %s\r",s1,s2);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- break;
- case F111: /* 7, "s1 s2: n" */
- x = strlen(s2);
- if (s2[x] == '\n' || s2[x] == '\r') s2[x] = '\0';
- if (strlen(s1) + x + 15 > TBUFL)
- sprintf(sp,"?T-Log string too long\r");
- else sprintf(sp,"%s %s: %ld\r",s1,s2,n);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- break;
- default:
- sprintf(sp,"\r?Invalid format for tlog() - %ld\r",n);
- if (zsout(ZTFILE,s) < 0) tralog = 0;
- }
- }
- #endif /* TLOG */
-
-
-
- short slogfile;
- char slogname[] = "Kermit Session";
-
- /****************************************************************************/
- /****************************************************************************/
- openslog ()
- {
- return (openlogfile("Session log name:", slogname, &slogfile, ZSFILE));
- }
-
-
- /****************************************************************************/
- /****************************************************************************/
- openlogfile(prompt, name, fdp, n)
- char *prompt, *name;
- short *fdp;
- int n;
- {
- int err;
- SFReply sfr; /* holds file info */
- Point where;
-
- SetPt(&where, 75, 80);
- SFPutFile (where,
- c2p_tmp(prompt),
- c2p_tmp2(name),
- (DlgHookProcPtr) NILPROC,
- &sfr);
- if (!sfr.good) /* if canceled */
- return (0);
-
- /* p2cstr(&sfr.fName); */
-
- err = Create (&sfr.fName, sfr.vRefNum, 'MACA', 'TEXT');
- if (err != dupFNErr)
- if (!ioutil (err))
- return (0);
-
- err = FSOpen (&sfr.fName, sfr.vRefNum, fdp); /* open the logfile */
- if (!ioutil (err))
- return (0);
-
- fp[n].frefnum = *fdp; /* let normal kermit z- routines know about */
- /* the file descriptor */
-
- SetFPos (*fdp, fsFromLEOF, 0); /* set file pointer to eof */
-
- return (1);
- } /* openslog */
-
-
-
- /****************************************************************************/
- /****************************************************************************/
- closeslog ()
- {
- int err;
-
- err = FSClose (slogfile);
- if (!ioutil (err))
- return (0);
- FlushVol (NIL, dfltVol);
- } /* closeslog */
-
-
-
- /****************************************************************************/
- /* write a maximum of n characters from s to the session log file */
- /* skip all trailing blanks */
- /****************************************************************************/
- slog (s, n)
- char *s;
- int n;
- {
- long count;
- char *c;
-
- /* skip all non visible characters */
- for (c = s + n - 1; (*c <= ' ') && (c >= s); c--);
-
- /* adjust count and write to file */
- count = (long) (c - s + 1);
- FSWrite (slogfile, &count, s);
-
- /* write a cr at end of line */
- count = 1;
- FSWrite (slogfile, &count, "\r");
- } /* slog */
-
- char plogname[] = "Kermit Packets";
-
- /****************************************************************************/
- /****************************************************************************/
- openplog ()
- {
- return (openlogfile("Packet log name:",
- plogname,
- &fp[ZPFILE].frefnum,
- ZPFILE));
- }
-
- /****************************************************************************/
- /****************************************************************************/
- closeplog ()
- {
- FSClose (fp[ZPFILE].frefnum);
- FlushVol (NIL, dfltVol);
- } /* closeplog */
-
- /****************************************************************************/
- /****************************************************************************/
- opendlog ()
- {
- /* debugging output goes to the console for the moment */
- return (zopeno (ZDFILE, "Debugging log file", NULL, NULL));
- }
-
- /****************************************************************************/
- /****************************************************************************/
- closedlog ()
- {
- return (zclose(ZDFILE));
- } /* closedlog */
-
-
- /****************************************************************************/
- /****************************************************************************/
- char *
- tilde_expand(dirname) char *dirname; {
- /* there really isn't any concept of "user's home dir" on the Mac */
- return("");
- }
-
- /* Z S T I M E -- Set creation date for incoming file */
- /*
- Call with:
- f = pointer to name of existing file.
- yy = pointer to a Kermit file attribute structure in which yy->date.val
- is a date of the form yyyymmdd hh:mm:ss, e.g. 19900208 13:00:00.
- x = is a function code: 0 means to set the file's creation date as given.
- 1 means compare the given date with the file creation date.
- Returns:
- -1 on any kind of error.
- 0 if x is 0 and the file date was set successfully.
- 0 if x is 1 and date from attribute structure <= file creation date.
- 1 if x is 1 and date from attribute structure > file creation date.
- */
-
- zstime(f,yy,x)
- char *f;
- struct zattr *yy;
- int x;
- {
- /* $$$ Fill me in */
- }
-
- #define WINDOW_MAGIC 0xFFF0 /* hopefully unused value */
-
- /*
- * mac_fopen
- * Open a window if special filename.
- *
- * We use these fields in the FILE struct:
- * _ptr - pointer to cmdw
- * _size - character offset of current position
- * _flag - holds our magic flag identifier
- */
- FILE *mac_fopen (char *filename, char *mode)
- {
- int id;
- struct cmdw *cmdw;
- extern struct cmdw *cmdwl;
- FILE *stream;
-
- if (strncmp(filename, "%%%", 3) != 0) /* if normal open */
- return(fopen(filename, mode));
-
- /*
- * Find the window
- */
- id = atoi(&filename[3]);
- for (cmdw = cmdwl; cmdw; cmdw = cmdw->next)
- if (id == cmdw->id)
- break;
- if (!cmdw)
- return NULL;
-
- /*
- * Allocate and preset FILE struct
- */
- stream = (FILE *)malloc(sizeof(FILE));
- if (!stream) {
- printfalert("mac_fopen: no memory for FILE");
- return NULL;
- }
- #ifdef MPW
- stream->_flag = WINDOW_MAGIC;
- stream->_size = 0;
- stream->_ptr = (unsigned char *)cmdw;
- #else /* !MPW */
-
- YOU MUST FIGURE OUT HOW TO DO THE SAME THING FOR NON-MPW ENVIRONMENTS!!!
-
- #endif /* MPW */
- cmdw->flags |= CMDWF_FOPEN;
-
- return(stream);
- }
-
-
- /*
- * mac_fclose
- */
- int mac_fclose (FILE *stream)
- {
- struct cmdw *cmdw;
-
- if (stream->_flag != WINDOW_MAGIC)
- return(fclose(stream));
-
- cmdw = (struct cmdw *)stream->_ptr;
- cmdw->flags &= ~CMDWF_FOPEN; /* clear file open */
-
- free(stream);
- return 0;
- }
-
-
- /*
- * mac_rewind
- */
- void mac_rewind (FILE *stream)
- {
- if (stream->_flag != WINDOW_MAGIC) {
- rewind(stream);
- return;
- }
-
- stream->_size = 0;
- }
-
-
- /*
- * mac_fgets
- */
- char *mac_fgets (char *s, int n, FILE *stream)
- {
- struct cmdw *cmdw;
- CharsHandle h;
- long len;
- char *cp;
- unsigned short fpos;
- int nstored;
-
- if (stream->_flag != WINDOW_MAGIC)
- return (fgets(s, n, stream));
-
- cmdw = (struct cmdw *)stream->_ptr;
- h = TEGetText(cmdw->teh);
- len = (*cmdw->teh)->teLength;
- cp = (char *)*h; /* pointer to chars in window */
- fpos = stream->_size; /* file position */
-
- if (fpos >= len) /* if already eof */
- return NULL;
-
- /*
- * Transfer characters until n-1 chars have been transfered,
- * a newline has been transferred, or we have reached the
- * end of the window. Terminate the buffer with a null.
- */
- nstored = 0;
- while (fpos < len) {
- if (nstored >= n-1)
- break;
- s[nstored] = cp[fpos++];
- if (s[nstored++] == '\n')
- break;
- }
- s[nstored++] = '\0'; /* terminate string */
- stream->_size = fpos; /* remember position */
-
- return s;
- }
-
-
- /*
- * mac_feof
- */
- int mac_feof (FILE *stream)
- {
- struct cmdw *cmdw;
- long len;
-
- if (stream->_flag != WINDOW_MAGIC)
- return(feof(stream));
-
- cmdw = (struct cmdw *)stream->_ptr;
- len = (*cmdw->teh)->teLength;
-
- if (stream->_size >= len)
- return TRUE;
- else
- return FALSE;
- }
-
-
- /*
- * Junk so Emacs will set local variables to be compatible with Mac/MPW.
- * Should be at end of file.
- * This module uses 8 char tabs
- *
- * Local Variables:
- * tab-width: 8
- * End:
- */
-